{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 引入时间\n",
    "\n",
    "我们聊天的时候，除了内容，时间也是很关键的信息。\n",
    "\n",
    "那么此时需要使用`datetime`库来记录每一条消息的发出时间。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "from flask import Flask, redirect\n",
    "\n",
    "app = Flask(__name__)\n",
    "messages = [] # 保存聊天信息\n",
    "\n",
    "\n",
    "def add_messages(username, message):\n",
    "    # 添加消息，保存在列表里面\n",
    "    now = datetime.now().strftime(\"%H:%M:%S\") # 记录时间：格式：00:00:00  - 年月日：%Y%m%d\n",
    "    messages.append(\"({}) {}: {}\".format(now, username, message))\n",
    "\n",
    "def get_all_messages():\n",
    "    \"\"\"获取关于我的所有聊天信息`\"\"\"\n",
    "    return \"<br>\".join(messages)\n",
    "\n",
    "@app.route(\"/\")\n",
    "def index():\n",
    "    \"\"\"首页\"\"\"\n",
    "    return \"<h1>欢迎光临</h1> <p> 发信息给某人可以这样: /USERNAME/MESSAGE </p>\"\n",
    "\n",
    "\n",
    "@app.route(\"/<username>\")\n",
    "def user(username):\n",
    "    \"\"\"显示所有消息\"\"\"\n",
    "    return \"<h1>欢迎, {0}</h1>{1}\".format(username, get_all_messages())\n",
    "\n",
    "\n",
    "@app.route(\"/<username>/<message>\")\n",
    "def send_message(username, message):\n",
    "    \"\"\"\n",
    "    通过路由设置:/人名称/信息内容 来实现发送信息给某人\n",
    "    添加信息到列表里面，然后返回到用户页面\n",
    "    \"\"\"\n",
    "    add_messages(username, message)\n",
    "    return redirect(\"/\" + username)\n",
    "\n",
    "app.run() # 启动服务器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 补充知识\n",
    "\n",
    "推荐HTML学习网站:\n",
    "\n",
    "https://www.runoob.com/html/html-tutorial.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 引入网页渲染模板\n",
    "\n",
    "在文件夹中添加`templates`文件夹，里面添加一个网页文档`index1.html`\n",
    "\n",
    "```\n",
    "<html>\n",
    "    <head>\n",
    "        <title>首页</title>\n",
    "    </head>\n",
    "    \n",
    "    <body>\n",
    "        <p>发送信息格式: /名字/消息内容 </p>\n",
    "    </body>\n",
    "</html>\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Serving Flask app '__main__' (lazy loading)\n",
      " * Environment: production\n",
      "\u001b[31m   WARNING: This is a development server. Do not use it in a production deployment.\u001b[0m\n",
      "\u001b[2m   Use a production WSGI server instead.\u001b[0m\n",
      " * Debug mode: off\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " * Running on all addresses.\n",
      "   WARNING: This is a development server. Do not use it in a production deployment.\n",
      " * Running on http://10.0.20.12:5000/ (Press CTRL+C to quit)\n",
      "113.70.248.211 - - [08/Jun/2022 15:09:37] \"GET / HTTP/1.1\" 200 -\n",
      "113.70.248.211 - - [08/Jun/2022 15:09:37] \"GET /favicon.ico HTTP/1.1\" 200 -\n"
     ]
    }
   ],
   "source": [
    "from datetime import datetime\n",
    "from flask import Flask, redirect, render_template\n",
    "\n",
    "app = Flask(__name__)\n",
    "messages = [] # 保存聊天信息\n",
    "\n",
    "\n",
    "def add_messages(username, message):\n",
    "    # 添加消息，保存在列表里面\n",
    "    now = datetime.now().strftime(\"%H:%M:%S\") # 记录时间：格式：00:00:00\n",
    "    messages.append(\"({}) {}: {}\".format(now, username, message))\n",
    "\n",
    "def get_all_messages():\n",
    "    \"\"\"获取关于我的所有聊天信息`\"\"\"\n",
    "    return \"<br>\".join(messages)\n",
    "\n",
    "\n",
    "@app.route(\"/\")\n",
    "def index():\n",
    "    \"\"\"主页\"\"\"\n",
    "    return render_template(\"index1.html\") # 加载我们的网页文档\n",
    "\n",
    "\n",
    "@app.route(\"/<username>\")\n",
    "def user(username):\n",
    "    \"\"\"显示所有消息\"\"\"\n",
    "    return \"<h1>欢迎, {0}</h1>{1}\".format(username, get_all_messages())\n",
    "\n",
    "\n",
    "@app.route(\"/<username>/<message>\")\n",
    "def send_message(username, message):\n",
    "    \"\"\"\n",
    "    通过路由设置:/人名称/信息内容 来实现发送信息给某人\n",
    "    添加信息到列表里面，然后返回到用户页面\n",
    "    \"\"\"\n",
    "    add_messages(username, message)\n",
    "    return redirect(\"/\" + username)\n",
    "\n",
    "app.run(host=\"0.0.0.0\") # 启动服务器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 让浏览器记住用户\n",
    "\n",
    "需要引入`Session`机制， 那么什么是`Session`?浏览器记住有两种，一种是缓存，一种是你主动去记住某些东西,缓存是浏览器自己做，session才是你编程去主动记住，并且能使用的.\n",
    "\n",
    "### 解释session：\n",
    "\n",
    "当访问服务器否个网页的时候，会在服务器端的内存里开辟一块内存，这块内存就叫做session，而这个内存是跟浏览器关联在一起的。这个浏览器指的是浏览器窗口，或者是浏览器的子窗口，意思就是，只允许当前这个session对应的浏览器访问，就算是在同一个机器上新启的浏览器也是无法访问的。而另外一个浏览器也需要记录session的话，就会再启一个属于自己的session.\n",
    "\n",
    "简单来说：session就是服务器里面的一块内存，内存里面能放任何东西，只要是名值对就可以了，类似Python里面的字典\n",
    "\n",
    "\n",
    "### 主页逻辑\n",
    "\n",
    "当用户第一次浏览网站的时候，`Session`中没有用户，\n",
    "\n",
    "那么我们就给一个表单，让用户填写用户名然后用`post`提交数据，然后把用户信息放到`Session`，\n",
    "\n",
    "然后下次打开网页就不需要登记用户名，服务器已经知道你是谁了。\n",
    "``"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Serving Flask app '__main__' (lazy loading)\n",
      " * Environment: production\n",
      "\u001b[31m   WARNING: This is a development server. Do not use it in a production deployment.\u001b[0m\n",
      "\u001b[2m   Use a production WSGI server instead.\u001b[0m\n",
      " * Debug mode: off\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " * Running on all addresses.\n",
      "   WARNING: This is a development server. Do not use it in a production deployment.\n",
      " * Running on http://10.0.20.12:5000/ (Press CTRL+C to quit)\n",
      "113.70.248.211 - - [08/Jun/2022 15:14:25] \"GET / HTTP/1.1\" 200 -\n",
      "113.70.248.211 - - [08/Jun/2022 15:14:25] \"GET /favicon.ico HTTP/1.1\" 200 -\n"
     ]
    }
   ],
   "source": [
    "from datetime import datetime\n",
    "from flask import Flask, redirect, render_template, request, session\n",
    "\n",
    "\n",
    "app = Flask(__name__)\n",
    "app.secret_key = \"randomstring12345\"  # 大家可以不一样的，用于生成随机ID的随机种子，类似random的seed\n",
    "messages = []\n",
    "\n",
    "\n",
    "def add_messages(username, message):\n",
    "    # 添加消息，保存在列表里面\n",
    "    now = datetime.now().strftime(\"%H:%M:%S\") # 记录时间：格式：00:00:00\n",
    "    messages.append(\"({}) {}: {}\".format(now, username, message))\n",
    "\n",
    "def get_all_messages():\n",
    "    \"\"\"获取关于我的所有聊天信息`\"\"\"\n",
    "    return \"<br>\".join(messages)\n",
    "\n",
    "\n",
    "\n",
    "@app.route(\"/\", methods=[\"GET\", \"POST\"])  # 允许的方法有POST和GET，其他不写methods默认就是GET\n",
    "def index():\n",
    "    \"\"\"主页\"\"\"\n",
    "    if request.method == \"POST\":\n",
    "        # 如果是POST请求，进入这里，在请求中把username放到session里面\n",
    "        session[\"username\"] = request.form[\"username\"]\n",
    "\n",
    "    if \"username\" in session:\n",
    "        # 如果session中有username这个键值，就转跳到对应的用户页面\n",
    "        return redirect(session[\"username\"])\n",
    "    \n",
    "    # 如果没有，就展示首页网页。\n",
    "    return render_template(\"index2.html\")\n",
    "\n",
    "\n",
    "@app.route(\"/<username>\")\n",
    "def user(username):\n",
    "    \"\"\"显示所有消息\"\"\"\n",
    "    return \"<h1>欢迎, {0}</h1>{1}\".format(username, get_all_messages())\n",
    "\n",
    "\n",
    "@app.route(\"/<username>/<message>\")\n",
    "def send_message(username, message):\n",
    "    \"\"\"\n",
    "    通过路由设置:/人名称/信息内容 来实现发送信息给某人\n",
    "    添加信息到列表里面，然后返回到用户页面\n",
    "    \"\"\"\n",
    "    add_messages(username, message)\n",
    "    return redirect(\"/\" + username)\n",
    "\n",
    "app.run(host=\"0.0.0.0\") # 启动服务器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 补充知识\n",
    "\n",
    "#### 浏览器将GET和POST定义为：\n",
    "\n",
    "在客户机和服务器之间进行请求-响应时，两种最常被用到的方法是：GET 和 POST。\n",
    "\n",
    "GET - 从指定的资源请求数据。\n",
    "\n",
    "POST - 向指定的资源提交要被处理的数据。\n",
    "\n",
    "学习参考链接：https://www.runoob.com/tags/html-httpmethods.html\n",
    "\n",
    "\n",
    "### 优化\n",
    "1. 聊天页面也引入一个html模板\n",
    "2. 聊天页面增加退出聊天功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
